home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / thesrc20.zip / box.c < prev    next >
C/C++ Source or Header  |  1995-01-26  |  14KB  |  399 lines

  1. /***********************************************************************/
  2. /* BOX.C -                                                             */
  3. /* This file contains all functions relating to box operations.        */
  4. /***********************************************************************/
  5. /*
  6.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  7.  * Copyright (C) 1991-1995 Mark Hessling
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as
  11.  * published by the Free Software Foundation; either version 2 of
  12.  * the License, or any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17.  * General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to:
  21.  *
  22.  *    The Free Software Foundation, Inc.
  23.  *    675 Mass Ave,
  24.  *    Cambridge, MA 02139 USA.
  25.  *
  26.  *
  27.  * If you make modifications to this software that you feel increases
  28.  * it usefulness for the rest of the community, please email the
  29.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  30.  * This software is going to be maintained and enhanced as deemed
  31.  * necessary by the community.
  32.  *
  33.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  34.  * 36 David Road                     Phone: +61 7 849 7731
  35.  * Holland Park                      Fax:   +61 7 875 5314
  36.  * QLD 4121
  37.  * Australia
  38.  */
  39.  
  40. /*
  41. $Id: box.c 2.0 1995/01/26 16:29:44 MH Release MH $
  42. */
  43.  
  44. #include <stdio.h>
  45.  
  46. #include "the.h"
  47. #include "proto.h"
  48.  
  49. /*#define DEBUG 1*/
  50. /***********************************************************************/
  51. #ifdef PROTO
  52. void box_operations(short action,CHARTYPE reset,bool overlay,CHARTYPE fillchar)
  53. #else
  54. void box_operations(action,reset,overlay,fillchar)
  55. short action;
  56. CHARTYPE reset;
  57. bool overlay;
  58. CHARTYPE fillchar;
  59. #endif
  60. /***********************************************************************/
  61. {
  62. /*-------------------------- external data ----------------------------*/
  63.  extern VIEW_DETAILS *vd_mark;
  64. /*--------------------------- local data ------------------------------*/
  65.  BOXP boxp;
  66.  short rc=RC_OK;
  67.  unsigned short y=0,x=0;
  68.  LENGTHTYPE offset=0;
  69.  short save_mark_type=MARK_VIEW->mark_type;
  70. /*--------------------------- processing ------------------------------*/
  71. #ifdef TRACE
  72.  trace_function("commutil.c:box_operations");
  73. #endif
  74. /*---------------------------------------------------------------------*/
  75. /* This procedure is for copying, deleting, filling, moving and        */
  76. /* overlaying box blocks. Box blocks consist of BOX, WORD and COLUMN   */
  77. /* blocks.                                                             */
  78. /*---------------------------------------------------------------------*/
  79.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  80. /*---------------------------------------------------------------------*/
  81. /* If the command was issued on the command line then the destination  */
  82. /* line is the current line and the destination column is 0;           */
  83. /*---------------------------------------------------------------------*/
  84.  if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  85.    {
  86.     if (CURRENT_VIEW->current_line == 0L)
  87.        boxp.dst_start_line = 1L;
  88.     else
  89.        boxp.dst_start_line = CURRENT_VIEW->current_line;
  90.     boxp.dst_start_col = 0;
  91.    }
  92.  else
  93.    {
  94.     if (CURRENT_VIEW->focus_line == 0L)
  95.        boxp.dst_start_line = 1L;
  96.     else
  97.        boxp.dst_start_line = CURRENT_VIEW->focus_line;
  98.     getyx(CURRENT_WINDOW,y,x);
  99.     boxp.dst_start_col = x + CURRENT_VIEW->verify_col-1;
  100.    }
  101.  
  102.  boxp.src_start_line = MARK_VIEW->mark_start_line;
  103.  boxp.src_start_col = MARK_VIEW->mark_start_col-1;
  104.  
  105.  boxp.num_cols =  MARK_VIEW->mark_end_col - MARK_VIEW->mark_start_col + 1;
  106. /*---------------------------------------------------------------------*/
  107. /* If the block type is COLUMN, the number of lines to operate on is   */
  108. /* the number of lines in the source file and the destination start    */
  109. /* line is line 1. Reset these values set above.                       */
  110. /*---------------------------------------------------------------------*/
  111.  if (MARK_VIEW->mark_type == M_COLUMN)
  112.    {
  113.     boxp.num_lines = MARK_VIEW->file_for_view->number_lines - boxp.src_start_line +1L;
  114.     boxp.dst_start_line = 1L;
  115.    }
  116.  else
  117.     boxp.num_lines = MARK_VIEW->mark_end_line - boxp.src_start_line +1L;
  118. /*---------------------------------------------------------------------*/
  119. /* Find the current LINE pointer for both the source and destination   */
  120. /* lines.                                                              */
  121. /*---------------------------------------------------------------------*/
  122.  boxp.curr_src = lll_find(MARK_FILE->first_line,boxp.src_start_line);
  123.  if (action != BOX_D)
  124.     boxp.curr_dst = lll_find(CURRENT_FILE->first_line,boxp.dst_start_line);
  125. /*---------------------------------------------------------------------*/
  126. /* Call the appropriate box function...                                */
  127. /*---------------------------------------------------------------------*/
  128.  boxp.action = action;
  129.  switch(action)
  130.    {
  131.     case BOX_D:
  132.         rc = box_delete(&boxp);
  133.         break;
  134.     case BOX_M:
  135.         rc = box_move(&boxp,overlay);
  136.         break;
  137.     case BOX_C:
  138. /*      rc = box_copy(&boxp,overlay);*/
  139.         rc = box_move(&boxp,overlay);
  140.         break;
  141.     case BOX_F:
  142.         rc = box_fill(&boxp,fillchar);
  143.         break;
  144.    }
  145.  if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  146.    {
  147. #ifdef TRACE
  148.     trace_return();
  149. #endif
  150.     return;  /* should return a value */
  151.    }
  152. /*---------------------------------------------------------------------*/
  153. /* Set the parameters in the MARK_VIEW to OFF;                         */
  154. /*---------------------------------------------------------------------*/
  155.  MARK_VIEW->marked_line = MARK_VIEW->marked_col = FALSE;
  156.  MARK_VIEW = (VIEW_DETAILS *)NULL;
  157. /*---------------------------------------------------------------------*/
  158. /* If we are not resetting the block, set up block markers...          */
  159. /*---------------------------------------------------------------------*/
  160.  if (reset != SOURCE_BLOCK_RESET)
  161.    {
  162.     if (boxp.src_start_col < boxp.dst_start_col
  163.     && action == BOX_M)
  164.        offset = boxp.num_cols;
  165.     MARK_VIEW = CURRENT_VIEW;
  166.     MARK_VIEW->mark_start_line = boxp.dst_start_line;
  167.     MARK_VIEW->mark_end_line = boxp.dst_start_line+boxp.num_lines-1L;
  168.     MARK_VIEW->mark_start_col = boxp.dst_start_col+1-offset;
  169.     MARK_VIEW->mark_end_col = boxp.dst_start_col+boxp.num_cols-offset;
  170.     MARK_VIEW->mark_type = save_mark_type;
  171.     MARK_VIEW->marked_line = MARK_VIEW->marked_col = TRUE;
  172.     wmove(CURRENT_WINDOW,y,x-offset);
  173.    }
  174.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  175.  build_current_screen(); 
  176.  display_current_screen(); /* should only call this is the marked block is in view */
  177. #ifdef TRACE
  178.  trace_return();
  179. #endif
  180.  return;
  181. }
  182. /***********************************************************************/
  183. #ifdef PROTO
  184. short box_delete(BOXP *prm)
  185. #else
  186. short box_delete(prm)
  187. BOXP *prm;
  188. #endif
  189. /***********************************************************************/
  190. {
  191. /*-------------------------- external data ----------------------------*/
  192.  extern VIEW_DETAILS *vd_mark;
  193. /*--------------------------- local data ------------------------------*/
  194.  LINETYPE i=0L;
  195.  LENGTHTYPE j=0;
  196.  short num_to_move=0;
  197. /*--------------------------- processing ------------------------------*/
  198. #ifdef TRACE
  199.  trace_function("commutil.c:box_delete");
  200. #endif
  201.  for (i=0L;i<prm->num_lines;i++)
  202.     {
  203.      num_to_move = prm->curr_src->length - MARK_VIEW->mark_end_col;
  204.      if (num_to_move < 0)
  205.          num_to_move = 0;
  206.      add_to_recovery_list(prm->curr_src->line,prm->curr_src->length);
  207.      prm->curr_src->length = min(prm->curr_src->length,prm->src_start_col+num_to_move);
  208.      for (j=0;j<num_to_move;j++)
  209.          *(prm->curr_src->line+j+prm->src_start_col) = *(prm->curr_src->line+prm->src_start_col+j+prm->num_cols);
  210.      *(prm->curr_src->line+prm->curr_src->length) = '\0';/* null terminate */
  211.      prm->curr_src = prm->curr_src->next;  /* this should NEVER go past the end */
  212.     }
  213. #ifdef TRACE
  214.  trace_return();
  215. #endif
  216.  return(RC_OK);
  217. }
  218. /***********************************************************************/
  219. #ifdef PROTO
  220. short box_move(BOXP *prm,bool overlay)
  221. #else
  222. short box_move(prm,overlay)
  223. BOXP *prm;
  224. bool overlay;
  225. #endif
  226. /***********************************************************************/
  227. {
  228. /*-------------------------- external data ----------------------------*/
  229.  extern CHARTYPE *rec;
  230.  extern unsigned short rec_len;
  231. /*--------------------------- local data ------------------------------*/
  232.  LINETYPE i=0L;
  233.  LINE *first_save=NULL,*save_src=NULL,*tmp=NULL;
  234.  bool copy_first=FALSE;
  235.  LINETYPE save_src_start_line=0L;
  236.  LENGTHTYPE save_src_start_col=0;
  237. /*--------------------------- processing ------------------------------*/
  238. #ifdef TRACE
  239.  trace_function("commutil.c:box_move");
  240. #endif
  241.  if (prm->dst_start_col > prm->src_start_col+prm->num_cols)
  242.     copy_first = TRUE;
  243.  save_src_start_col = prm->src_start_col;
  244.  save_src_start_line = prm->src_start_line;
  245.  if (copy_first)
  246.    {
  247.     save_src = prm->curr_src;
  248.     box_copy(prm,overlay);
  249.     prm->src_start_line = save_src_start_line;
  250.     prm->src_start_col = save_src_start_col;
  251.     prm->curr_src = save_src;
  252.     if (prm->action == BOX_M)
  253.        box_delete(prm);
  254.    }
  255.  else
  256.    {
  257. /*---------------------------------------------------------------------*/
  258. /* Save the data that is to be deleted. It is saved in a format that   */
  259. /* can be used in copy_box() as the src line pointer.                  */
  260. /*---------------------------------------------------------------------*/
  261.     tmp = prm->curr_src;
  262.     for (i=0L;i<prm->num_lines;i++)
  263.        {
  264.         memset(rec,' ',max_line_length);       /* copy line into rec[] */
  265.         memcpy(rec,tmp->line,tmp->length);
  266.         rec_len = tmp->length;
  267.         if ((save_src = add_line(first_save,save_src,
  268.             rec+prm->src_start_col,prm->num_cols,0)) == (LINE *)NULL)
  269.           {
  270. #ifdef TRACE
  271.            trace_return();
  272. #endif
  273.            return(RC_OUT_OF_MEMORY);
  274.           }
  275.         if (first_save == (LINE *)NULL)
  276.            first_save = save_src;
  277.         tmp = tmp->next;
  278.        }
  279.     if (prm->action == BOX_M)
  280.        box_delete(prm);
  281.     prm->src_start_line = 0L;
  282.     prm->src_start_col = 0;
  283.     prm->curr_src = first_save;
  284.     box_copy(prm,overlay);
  285.     first_save = lll_free(first_save);
  286.     prm->src_start_line = save_src_start_line;
  287.     prm->src_start_col = save_src_start_col;
  288.    }
  289. #ifdef TRACE
  290.  trace_return();
  291. #endif
  292.  return(RC_OK);
  293. }
  294. /***********************************************************************/
  295. #ifdef PROTO
  296. short box_copy(BOXP *prm,bool overlay)
  297. #else
  298. short box_copy(prm,overlay)
  299. BOXP *prm;
  300. bool overlay;
  301. #endif
  302. /***********************************************************************/
  303. {
  304. /*-------------------------- external data ----------------------------*/
  305.  extern CHARTYPE *rec;
  306.  extern unsigned short rec_len;
  307. /*--------------------------- local data ------------------------------*/
  308.  LINETYPE i=0L;
  309.  LENGTHTYPE j=0;
  310.  CHARTYPE chr=0;
  311.  short rc=RC_OK;
  312. /*--------------------------- processing ------------------------------*/
  313. #ifdef TRACE
  314.  trace_function("commutil.c:box_copy");
  315. #endif
  316.  for (i=0L;i<prm->num_lines;i++)
  317.     {
  318.      if (prm->curr_dst->next == (LINE *)NULL)  /* on *** Bottom of File *** */
  319.        {
  320.         if ((prm->curr_dst = add_line(CURRENT_FILE->first_line,prm->curr_dst->prev,
  321.                                  (CHARTYPE *)"",0,0)) == (LINE *)NULL)
  322.           {
  323. #ifdef TRACE
  324.            trace_return();
  325. #endif
  326.            return(RC_OUT_OF_MEMORY);
  327.           }
  328.         CURRENT_FILE->number_lines++;
  329.        }
  330.      pre_process_line(CURRENT_VIEW,prm->dst_start_line+i);/* copy dest line into rec */
  331.      for (j=0;j<prm->num_cols;j++)
  332.         {
  333.          if (prm->src_start_col+j+1 > prm->curr_src->length)
  334.             chr = (CHARTYPE)' ';
  335.          else
  336.             chr = (CHARTYPE)*(prm->curr_src->line+prm->src_start_col+j);
  337.          if (overlay)
  338.             rec[prm->dst_start_col+j] = chr;
  339.          else
  340.             meminschr(rec,chr,prm->dst_start_col+j,max_line_length,rec_len++);
  341.         }
  342.      rc = memrevne(rec,' ',max_line_length);
  343.      if (rc == (-1))
  344.         rec_len = 0;
  345.      else
  346.         rec_len = rc+1;
  347.      post_process_line(CURRENT_VIEW,prm->dst_start_line+i);
  348.      prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  349.      prm->curr_dst = prm->curr_dst->next;   /* this should NEVER go past the end */
  350.     }
  351. #ifdef TRACE
  352.  trace_return();
  353. #endif
  354.  return(RC_OK);
  355. }
  356. /***********************************************************************/
  357. #ifdef PROTO
  358. short box_fill(BOXP *prm,CHARTYPE fillchar)
  359. #else
  360. short box_fill(prm,fillchar)
  361. BOXP *prm;
  362. CHARTYPE fillchar;
  363. #endif
  364. /***********************************************************************/
  365. {
  366. /*-------------------------- external data ----------------------------*/
  367.  extern CHARTYPE *rec;
  368.  extern unsigned short rec_len;
  369. /*--------------------------- local data ------------------------------*/
  370.  LINETYPE i=0L;
  371.  LENGTHTYPE j=0;
  372.  short rc=RC_OK;
  373. /*--------------------------- processing ------------------------------*/
  374. #ifdef TRACE
  375.  trace_function("commutil.c:box_fill");
  376. #endif
  377.  for (i=0L;i<prm->num_lines;i++)
  378.     {
  379.      pre_process_line(CURRENT_VIEW,prm->src_start_line+i);/* copy source line into rec */
  380.      for (j=0;j<prm->num_cols;j++)
  381.          rec[prm->src_start_col+j] = fillchar;
  382.      rc = memrevne(rec,' ',max_line_length);
  383.      if (rc == (-1))
  384.         rec_len = 0;
  385.      else
  386.         rec_len = rc+1;
  387.      post_process_line(CURRENT_VIEW,prm->src_start_line+i);
  388.      prm->curr_src = prm->curr_src->next;   /* this should NEVER go past the end */
  389.     }
  390.  
  391.  prm->dst_start_col = prm->src_start_col;
  392.  prm->dst_start_line = prm->src_start_line;
  393.  
  394. #ifdef TRACE
  395.  trace_return();
  396. #endif
  397.  return(RC_OK);
  398. }
  399.